//
//  PopupModifier.swift
//  DocScaner
//
//  Created by liyahao on 2025/8/11.
//

import SwiftUI

// MARK: - 弹窗动画方向枚举
enum PopupDirection {
    case top
    case bottom
    case left
    case right
    case center
}

// MARK: - 弹窗配置结构体
struct PopupConfig {
    var direction: PopupDirection = .center
    var backgroundColor: Color = Color.black.opacity(0.5)
    var animationDuration: Double = 0.3
    var cornerRadius: CGFloat = 12
    var shadowRadius: CGFloat = 10
    var dismissOnBackgroundTap: Bool = true
    var padding: EdgeInsets = EdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 20)
}

// MARK: - 弹窗视图修饰器
struct PopupModifier<PopupContent: View>: ViewModifier {
    @Binding var isPresented: Bool
    let config: PopupConfig
    let popupContent: () -> PopupContent
    
    @State private var offset: CGSize = .zero
    @State private var opacity: Double = 0
    @State private var scale: CGFloat = 0.8
    
    func body(content: Content) -> some View {
        content
            .overlay(
                // 背景遮罩层
                Group {
                    if isPresented {
                        config.backgroundColor
                            .ignoresSafeArea()
                            .onTapGesture {
                                if config.dismissOnBackgroundTap {
                                    dismiss()
                                }
                            }
                            .overlay(
                                popupContent()
                                    .background(
                                        RoundedRectangle(cornerRadius: config.cornerRadius)
                                            .fill(Color(.systemBackground))
                                            .shadow(radius: config.shadowRadius)
                                    )
                                    .padding(config.padding)
                                    .frame(
                                        maxWidth: config.direction == .left || config.direction == .right ? .infinity : nil,
                                        maxHeight: config.direction == .top || config.direction == .bottom ? .infinity : nil,
                                        alignment: getAlignment()
                                    )
                                    .offset(offset)
                                    .opacity(opacity)
                                    .scaleEffect(config.direction == .center ? scale : 1.0)
                                    .ignoresSafeArea()
                            )
                    }
                }
            )
            .dcChange(of: isPresented) { old, newValue in
                if newValue {
                    show()
                } else {
                    dismiss()
                }
            }
    }
    
    // MARK: - 获取对齐方式
    private func getAlignment() -> Alignment {
        switch config.direction {
        case .top:
            return .top
        case .bottom:
            return .bottom
        case .left:
            return .leading
        case .right:
            return .trailing
        case .center:
            return .center
        }
    }
    
    // MARK: - 显示动画
    private func show() {
        // 设置初始状态
        setupInitialState()
        
        withAnimation(.easeOut(duration: config.animationDuration)) {
            offset = .zero
            opacity = 1.0
            scale = 1.0
        }
    }
    
    // MARK: - 隐藏动画
    private func dismiss() {
        withAnimation(.easeIn(duration: config.animationDuration)) {
            setupInitialState()
        } completion: {
            isPresented = false
        }
    }
    
    // MARK: - 设置初始状态
    private func setupInitialState() {
        switch config.direction {
        case .top:
            offset = CGSize(width: 0, height: -UIScreen.main.bounds.height)
            opacity = 1.0
            scale = 1.0
        case .bottom:
            offset = CGSize(width: 0, height: UIScreen.main.bounds.height)
            opacity = 1.0
            scale = 1.0
        case .left:
            offset = CGSize(width: -UIScreen.main.bounds.width, height: 0)
            opacity = 1.0
            scale = 1.0
        case .right:
            offset = CGSize(width: UIScreen.main.bounds.width, height: 0)
            opacity = 1.0
            scale = 1.0
        case .center:
            offset = .zero
            opacity = 0.0
            scale = 0.8
        }
    }
}

// MARK: - View扩展
extension View {
    func popup<Content: View>(
        isPresented: Binding<Bool>,
        config: PopupConfig = PopupConfig(),
        @ViewBuilder content: @escaping () -> Content
    ) -> some View {
        self.modifier(PopupModifier(isPresented: isPresented, config: config, popupContent: content))
    }
}

// MARK: - 预设弹窗样式
extension PopupConfig {
    // 警告弹窗
    static var alert: PopupConfig {
        var config = PopupConfig()
        config.direction = .center
        config.backgroundColor = Color.black.opacity(0.6)
        config.cornerRadius = 16
        config.shadowRadius = 20
        return config
    }
    
    // 底部弹窗
    static var bottomSheet: PopupConfig {
        var config = PopupConfig()
        config.direction = .bottom
        config.backgroundColor = Color.black.opacity(0.3)
        config.cornerRadius = 20
        config.padding = EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
        return config
    }
    
    // 侧边栏
    static var sidebar: PopupConfig {
        var config = PopupConfig()
        config.direction = .left
        config.backgroundColor = Color.black.opacity(0.4)
        config.cornerRadius = 0
        config.padding = EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 100)
        return config
    }
    
    // 顶部通知
    static var topNotification: PopupConfig {
        var config = PopupConfig()
        config.direction = .top
        config.backgroundColor = Color.clear
        config.cornerRadius = 12
        config.shadowRadius = 8
        config.dismissOnBackgroundTap = false
        config.padding = EdgeInsets(top: 50, leading: 20, bottom: 0, trailing: 20)
        return config
    }
}

// MARK: - 使用示例
struct AlertContentView: View {
    @State private var showAlert = false
    @State private var showBottomSheet = false
    @State private var showSidebar = false
    @State private var showTopNotification = false
    @State private var showCustom = false
    
    var body: some View {
        NavigationView {
            VStack(spacing: 20) {
                Text("SwiftUI 弹窗控件演示")
                    .font(.title)
                    .fontWeight(.bold)
                    .padding()
                
                VStack(spacing: 15) {
                    Button("显示中心弹窗 (Alert)") {
                        showAlert = true
                    }
                    .buttonStyle(CustomButtonStyle())
                    
                    Button("显示底部弹窗 (Bottom Sheet)") {
                        showBottomSheet = true
                    }
                    .buttonStyle(CustomButtonStyle())
                    
                    Button("显示侧边栏 (Sidebar)") {
                        showSidebar = true
                    }
                    .buttonStyle(CustomButtonStyle())
                    
                    Button("显示顶部通知 (Top Notification)") {
                        showTopNotification = true
                    }
                    .buttonStyle(CustomButtonStyle())
                    
                    Button("显示自定义弹窗") {
                        showCustom = true
                    }
                    .buttonStyle(CustomButtonStyle(color: .purple))
                }
                
                Spacer()
            }
            .navigationBarHidden(true)
            .background(Color(.systemGroupedBackground))
        }
        
        // 中心弹窗 - 警告样式
        .popup(isPresented: $showAlert, config: .alert) {
            VStack(spacing: 20) {
                Image(systemName: "exclamationmark.triangle.fill")
                    .font(.system(size: 50))
                    .foregroundColor(.orange)
                
                Text("警告")
                    .font(.headline)
                    .fontWeight(.bold)
                
                Text("这是一个警告弹窗示例，您确定要继续操作吗？")
                    .multilineTextAlignment(.center)
                    .foregroundColor(.secondary)
                
                HStack(spacing: 15) {
                    Button("取消") {
                        showAlert = false
                    }
                    .foregroundColor(.secondary)
                    
                    Button("确定") {
                        showAlert = false
                    }
                    .fontWeight(.semibold)
                    .foregroundColor(.white)
                    .padding(.horizontal, 20)
                    .padding(.vertical, 8)
                    .background(Color.blue)
                    .cornerRadius(8)
                }
            }
            .padding(30)
        }
        
        // 底部弹窗
        .popup(isPresented: $showBottomSheet, config: .bottomSheet) {
            VStack(alignment: .leading, spacing: 0) {
                // 拖拽指示器
                RoundedRectangle(cornerRadius: 2)
                    .fill(Color.secondary.opacity(0.3))
                    .frame(width: 40, height: 4)
                    .frame(maxWidth: .infinity)
                    .padding(.top, 12)
                    .padding(.bottom, 20)
                
                Text("底部弹窗")
                    .font(.title2)
                    .fontWeight(.bold)
                    .padding(.horizontal, 20)
                    .padding(.bottom, 15)
                
                VStack(alignment: .leading, spacing: 12) {
                    ForEach(["选项 1", "选项 2", "选项 3", "选项 4"], id: \.self) { option in
                        Button(action: {
                            showBottomSheet = false
                        }) {
                            HStack {
                                Image(systemName: "checkmark.circle")
                                    .foregroundColor(.blue)
                                Text(option)
                                    .foregroundColor(.primary)
                                Spacer()
                            }
                            .padding(.horizontal, 20)
                            .padding(.vertical, 12)
                        }
                    }
                }
                .padding(.bottom, 30)
            }
            .background(Color(.systemBackground))
            .cornerRadius(20, corners: [.topLeft, .topRight])
            
        }
        
        // 侧边栏
        .popup(isPresented: $showSidebar, config: .sidebar) {
            VStack(alignment: .leading, spacing: 0) {
                HStack {
                    Text("菜单")
                        .font(.title2)
                        .fontWeight(.bold)
                    Spacer()
                    Button(action: {
                        showSidebar = false
                    }) {
                        Image(systemName: "xmark")
                            .foregroundColor(.secondary)
                    }
                }
                .padding(20)
                .background(Color(.systemGray6))
                
                VStack(alignment: .leading, spacing: 0) {
                    ForEach(["首页", "设置", "帮助", "关于"], id: \.self) { item in
                        Button(action: {
                            showSidebar = false
                        }) {
                            HStack {
                                Image(systemName: "house")
                                    .frame(width: 20)
                                Text(item)
                                    .foregroundColor(.primary)
                                Spacer()
                            }
                            .padding(20)
                        }
                        
                        if item != "关于" {
                            Divider()
                                .padding(.leading, 20)
                        }
                    }
                }
                
                Spacer()
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
            .background(Color(.systemBackground))
        }
        
        // 顶部通知
        .popup(isPresented: $showTopNotification, config: .topNotification) {
            HStack {
                Image(systemName: "checkmark.circle.fill")
                    .foregroundColor(.green)
                    .font(.title3)
                
                VStack(alignment: .leading, spacing: 4) {
                    Text("操作成功")
                        .fontWeight(.semibold)
                    Text("您的操作已成功完成")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
                
                Spacer()
                
                Button(action: {
                    showTopNotification = false
                }) {
                    Image(systemName: "xmark")
                        .foregroundColor(.secondary)
                        .font(.caption)
                }
            }
            .padding(16)
            .background(Color(.systemBackground))
            .cornerRadius(12)
            .shadow(radius: 8)
            .onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                    showTopNotification = false
                }
            }
        }
        
        // 自定义弹窗
        .popup(isPresented: $showCustom, config: PopupConfig(
            direction: .right,
            backgroundColor: Color.purple.opacity(0.3),
            animationDuration: 0.5,
            cornerRadius: 25,
            shadowRadius: 15
        )) {
            VStack(spacing: 20) {
                Image(systemName: "star.fill")
                    .font(.system(size: 60))
                    .foregroundColor(.purple)
                
                Text("自定义弹窗")
                    .font(.title)
                    .fontWeight(.bold)
                
                Text("这是一个从右侧滑入的自定义弹窗，具有紫色主题和较长的动画时间。")
                    .multilineTextAlignment(.center)
                    .foregroundColor(.secondary)
                
                Button("关闭") {
                    showCustom = false
                }
                .foregroundColor(.white)
                .padding(.horizontal, 30)
                .padding(.vertical, 12)
                .background(Color.purple)
                .cornerRadius(20)
            }
            .padding(40)
        }
    }
}

// MARK: - 自定义按钮样式
struct CustomButtonStyle: ButtonStyle {
    var color: Color = .blue
    
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(.white)
            .padding(.vertical, 12)
            .padding(.horizontal, 20)
            .background(
                RoundedRectangle(cornerRadius: 10)
                    .fill(color)
                    .scaleEffect(configuration.isPressed ? 0.95 : 1.0)
            )
            .animation(.easeInOut(duration: 0.1), value: configuration.isPressed)
    }
}

// MARK: - 圆角扩展
extension View {
    func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
        clipShape(RoundedCorner(radius: radius, corners: corners))
    }
}

struct RoundedCorner: Shape {
    var radius: CGFloat = .infinity
    var corners: UIRectCorner = .allCorners

    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(
            roundedRect: rect,
            byRoundingCorners: corners,
            cornerRadii: CGSize(width: radius, height: radius)
        )
        return Path(path.cgPath)
    }
}

#Preview {
    AlertContentView()
}

